package com.lvchen.ui.fourfunction.photograph;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.view.SurfaceHolder;


import com.lvchen.common.utils.CamParaUtil;
import com.lvchen.common.utils.DisyplayUtils;

import java.io.IOException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class CameraInterface {
	private Camera mCamera;
	private Camera.Parameters mParams;
	private boolean isPreviewing = false;
	private float mPreviwRate = -1f;
	private static CameraInterface mCameraInterface;
	private int DST_RECT_WIDTH, DST_RECT_HEIGHT;

	private int mDefaultCameraId;// 当前真正打开的摄像头
	private int mNumberOfCameras = 0;

	private int flag;

	private TransmitDataCallback transmitDataCallback;

	private boolean mIsAutoFocus;
	private boolean mIsFocusing=false;
	private Timer mTimer;
	private TimerTask mTimerTask;

	// 优先选择打开的摄像头，默认后置
	private int firstCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;

	private Context context;

	public interface CamOpenOverCallback{
		public void cameraHasOpened();
	}

	private CameraInterface(){

	}

	public static synchronized CameraInterface getInstance(){
		if(mCameraInterface == null){
			mCameraInterface = new CameraInterface();
		}
		return mCameraInterface;
	}


	/**打开Camera
	 * @param callback
	 */
	public void doOpenCamera(CamOpenOverCallback callback){
		mCamera = getCameraInstance(firstCameraId);
		callback.cameraHasOpened();
	}

	/**
	 *  安全获取Camera对象实例的方法
	 * @param cameraId  优先打开的摄像头
	 * @return
	 */
	private Camera getCameraInstance(int cameraId) {
		Camera c = null;
		try {
			mNumberOfCameras = Camera.getNumberOfCameras();
			boolean bFind = false;
			Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
			for (int i = 0; i < mNumberOfCameras; i++) {
				Camera.getCameraInfo(i, cameraInfo);
				if (cameraInfo.facing == cameraId) {
					mDefaultCameraId = i;
					bFind = true;
					break;
				}
			}
			if (bFind)
				c = Camera.open(mDefaultCameraId); // 试图获取Camera实例
			else {
				mDefaultCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
				c = Camera.open(mDefaultCameraId);
			}
		} catch (Exception e) {
			// 摄像头不可用（正被占用或不存在）
			return null;
		}

		return c; // 不可用则返回null
	}

	/**使用Surfaceview开启预览
	 * @param holder
	 * @param previewRate
	 */
	public void doStartPreview(SurfaceHolder holder, float previewRate){
		if(isPreviewing){
			mCamera.stopPreview();
			return;
		}
		if(mCamera != null){
			try {
				mCamera.setPreviewDisplay(holder);
			} catch (IOException e) {
				e.printStackTrace();
			}
			initCamera(previewRate);
		}
	}

	/**
	 * 停止预览，释放Camera
	 */
	public void doStopCamera(){
		if(null != mCamera){
			mCamera.setPreviewCallback(null);
			mCamera.stopPreview();
			isPreviewing = false;
			mPreviwRate = -1f;
			mCamera.release();
			mCamera = null;
		}
	}

	/**
	 * 拍照
	 */
	public void doTakePicture(int w, int h){
		if(isPreviewing && (mCamera != null)){
			DST_RECT_WIDTH = w;
			DST_RECT_HEIGHT = h;
			mCamera.takePicture(mShutterCallback, mRawCallback, mRectJpegPictureCallback);
		}
	}

	public Point doGetPrictureSize(){
		Size s = mCamera.getParameters().getPictureSize();
		return new Point(s.width, s.height);
	}

	private void initCamera(float previewRate){
		if(mCamera != null){
			mParams = mCamera.getParameters();
			mParams.setPictureFormat(PixelFormat.JPEG);//设置拍照后存储的图片格式
			Size pictureSize = CamParaUtil.getInstance().getPropPictureSize(mParams.getSupportedPictureSizes(),previewRate, 800);
			mParams.setPictureSize(pictureSize.width, pictureSize.height);
			Size previewSize = CamParaUtil.getInstance().getPropPreviewSize(mParams.getSupportedPreviewSizes(),previewRate, 800);
			mParams.setPreviewSize(previewSize.width, previewSize.height);

			mCamera.setDisplayOrientation(90);

			List<String> focusModes = mParams.getSupportedFocusModes();
			if(focusModes.contains("continuous-video")){
				mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
			}

			mCamera.setParameters(mParams);
			mCamera.startPreview();//开启预览
			isPreviewing = true;

			mPreviwRate = previewRate;
			mParams = mCamera.getParameters(); //重新get一次
		}
	}


	/*为了实现拍照的快门声音及拍照保存照片需要下面三个回调变量*/
	ShutterCallback mShutterCallback = new ShutterCallback(){//快门按下的回调，在这里我们可以设置类似播放“咔嚓”声之类的操作。默认的就是咔嚓。
		public void onShutter() {
		}
	};

	PictureCallback mRawCallback = new PictureCallback(){// 拍摄的未压缩原数据的回调,可以为null
		public void onPictureTaken(byte[] data, Camera camera) {
		}
	};

	//自动聚焦
	public void startFocus(){
		mIsFocusing=true;
		mTimer = new Timer();
		mTimerTask = new CameraTimerTask();
		mTimer.schedule(mTimerTask, 0, 500);
	}

	public void stopFocus(){
		mIsFocusing=false;
		if (mTimerTask!=null) {
			mTimerTask.cancel();
			mTimerTask=null;
		}
	}


	class CameraTimerTask extends TimerTask {
		@Override
		public void run() {
			if (mCamera != null&&isPreviewing) {
				mCamera.autoFocus(mAutoFocusCallback);
			}
		}
	}

	private Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
		public void onAutoFocus(boolean success, Camera camera) {
			// TODO Auto-generated method stub
			if (success) {
				System.out.println("自动聚焦成功---------------------------------");
			}else {
				System.out.println("自动聚焦失败---------------------------------");
			}

		}
	};

	/**
	 * 拍摄指定区域的Rect
	 */
	PictureCallback mRectJpegPictureCallback = new PictureCallback(){//对jpeg图像数据的回调,最重要的一个回调
		public void onPictureTaken(byte[] data, Camera camera) {
			Bitmap b = null;
			if(null != data){
				System.out.println("图片大小======"+data.length);
				b = BitmapFactory.decodeByteArray(data, 0, data.length);//data是字节数据，将其解析成位图
				mCamera.stopPreview();
				isPreviewing = false;
			}else {
				mCamera.startPreview();
				isPreviewing = true;
			}
			//保存图片到sdcard
			if(null != b){
				//设置FOCUS_MODE_CONTINUOUS_VIDEO)之后，myParam.set("rotation", 90)失效。
				//图片竟然不能旋转了，故这里要旋转下
				Bitmap rotaBitmap = DisyplayUtils.getRotateBitmap(b, 90.0f);
				int x = rotaBitmap.getWidth()/2 - DST_RECT_WIDTH/2;
				int y = rotaBitmap.getHeight()/2 - DST_RECT_HEIGHT/2;

				System.out.println("x==============="+x);
				System.out.println("y==============="+y);
				System.out.println("rotaBitmap.getWidth()/2==============="+rotaBitmap.getWidth()/2);
				System.out.println("rotaBitmap.getHeight()/2==============="+rotaBitmap.getHeight()/2);
				System.out.println("宽==============="+DST_RECT_WIDTH/2);
				System.out.println("高==============="+DST_RECT_HEIGHT/2);

				Bitmap rectBitmap = Bitmap.createBitmap(rotaBitmap, x, y, DST_RECT_WIDTH, DST_RECT_HEIGHT);
				String filename= DisyplayUtils.saveBitmap(context,rectBitmap,flag);

				System.out.println("图片地址==============="+filename);

				rectBitmap.recycle();//自由选择是否进行回收
				if(rotaBitmap.isRecycled()){
					rotaBitmap.recycle();
					rotaBitmap = null;
				}
				if(rectBitmap.isRecycled()){
					rectBitmap.recycle();
					rectBitmap = null;
				}

				transmitDataCallback.TransmitData(filename);

			}

			if(!b.isRecycled()){
				b.recycle();
				b = null;
			}
		}
	};



	public interface TransmitDataCallback{
		public void TransmitData(String filename);
	}


	public void setTransmitDataCallback(TransmitDataCallback transmitDataCallback) {
		this.transmitDataCallback = transmitDataCallback;
	}

	//再次进入预览
	public void againPreview(){
		mCamera.startPreview();
		isPreviewing = true;
	}

	public int getFlag() {
		return flag;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	public Context getContext() {
		return context;
	}

	public void setContext(Context context) {
		this.context = context;
	}
}

